package com.yt.sys.api.client;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.toolkit.CollectionUtils;
import com.yt.common.constant.Result;
import com.yt.common.enums.CodeEnum;
import com.yt.common.utils.StrUtils;
import com.yt.sys.models.bo.SysRoleSaveBO;
import com.yt.sys.models.dto.SysPermissionDTO;
import com.yt.sys.models.dto.SysRoleDTO;
import com.yt.sys.models.service.ISysPermissionService;
import com.yt.sys.models.service.ISysRolePermissionService;
import com.yt.sys.models.service.ISysRoleService;
import com.yt.sys.models.vo.SysPermissionVO;
import com.yt.sys.models.vo.SysRolePermissionVO;
import com.yt.sys.models.vo.SysRoleVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/sysRole")
@Slf4j
@Api(value = "SysRoleApiController", tags = "角色信息Api接口")
public class SysRoleApiController {

    @DubboReference
    private ISysRoleService sysRoleService;
    @DubboReference
    private ISysRolePermissionService sysRolePermissionService;
    @DubboReference
    private ISysPermissionService sysPermissionService;

    @ApiOperation(value = "新增角色", notes = "新增角色信息")
    @PostMapping("/add")
    public Result<SysRoleVO> add(@RequestBody SysRoleSaveBO saveBO) {
        // 参数校验
        if (StrUtils.isEmpty(saveBO.getRoleName()) || saveBO.getStatus() == null) {
            return new Result<>(CodeEnum.FAIL_100002);
        }

        boolean success = sysRoleService.add(saveBO);
        if (success) {
            // 查询新增的角色信息
            SysRoleDTO dto = sysRoleService.selectOne(
                    new EntityWrapper<SysRoleDTO>()
                            .eq("role_name", saveBO.getRoleName())
                            .orderBy("create_time", false)
                            .last("LIMIT 1")
            );
            if (dto == null) {
                return new Result<>(CodeEnum.FAIL_100010); // 新增成功但查询失败
            }
            SysRoleVO vo = new SysRoleVO();
            BeanUtils.copyProperties(dto, vo);
            return new Result<>(vo);
        }
        return new Result<>(CodeEnum.FAIL_100007);
    }

    @GetMapping("/list")
    public Result<Page<SysRoleVO>> list(
            Integer status,
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize) {

        // 查询角色分页数据（原有逻辑）
        Page<SysRoleDTO> page = new Page<>(pageNum, pageSize);
        Wrapper<SysRoleDTO> wrapper = new EntityWrapper<>();
        if (status != null) {
            wrapper.eq("status", status);
        }
        wrapper.orderBy("create_time", false);
        Page<SysRoleDTO> dtoPage = sysRoleService.selectPage(page, wrapper);
        Page<SysRoleVO> voPage = new Page<>(dtoPage.getCurrent(), dtoPage.getSize());
        voPage.setTotal(dtoPage.getTotal());

        //DTO转VO基础信息
        List<SysRoleVO> voList = dtoPage.getRecords().stream()
                .map(dto -> {
                    SysRoleVO vo = new SysRoleVO();
                    BeanUtils.copyProperties(dto, vo);
                    return vo;
                }).collect(Collectors.toList());

        // 批量查询角色关联的权限，构建角色-权限树
        if (!CollectionUtils.isEmpty(voList)) {
            // 提取当前页所有角色ID
            List<Long> roleIds = voList.stream()
                    .map(SysRoleVO::getId)
                    .collect(Collectors.toList());

            // 联表查询角色-权限关联关系
            Map<String, Object> params = new HashMap<>();
            params.put("roleId", roleIds); // 传入角色ID列表，
            Page<SysRolePermissionVO> relationPage = new Page<>(1, Integer.MAX_VALUE);
            Page<SysRolePermissionVO> relationResult = sysRolePermissionService.selectRolePermissionPage(relationPage, params);

            // 提取所有关联的权限ID（去重）
            List<Long> permissionIds = relationResult.getRecords().stream()
                    .map(SysRolePermissionVO::getPermissionId)
                    .distinct()
                    .collect(Collectors.toList());

            // 批量查询权限详情
            Map<Long, SysPermissionVO> permissionMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(permissionIds)) {
                List<SysPermissionDTO> permissionDtos = sysPermissionService.selectBatchIds(permissionIds);
                permissionMap = permissionDtos.stream()
                        .map(dto -> {
                            SysPermissionVO vo = new SysPermissionVO();
                            BeanUtils.copyProperties(dto, vo);
                            return vo;
                        })
                        .collect(Collectors.toMap(SysPermissionVO::getId, Function.identity()));
            }

            // 按角色ID分组权限ID
            Map<Long, List<Long>> rolePermissionIdMap = relationResult.getRecords().stream()
                    .collect(Collectors.groupingBy(
                            SysRolePermissionVO::getRoleId,
                            Collectors.mapping(SysRolePermissionVO::getPermissionId, Collectors.toList())
                    ));

            // 为每个角色设置权限列表
            for (SysRoleVO roleVo : voList) {
                List<Long> permissionIdsOfRole = rolePermissionIdMap.getOrDefault(roleVo.getId(), Collections.emptyList());
                List<SysPermissionVO> permissions = permissionIdsOfRole.stream()
                        .map(permissionMap::get)
                        .filter(Objects::nonNull) // 过滤无效权限
                        .collect(Collectors.toList());
                roleVo.setPermissions(permissions);
            }
        }

        voPage.setRecords(voList);
        return new Result<>(voPage);
    }

    @ApiOperation(value = "查询角色详情", notes = "根据ID查询角色详情")
    @ApiImplicitParam(name = "id", value = "角色ID", required = true, paramType = "path", dataType = "Long")
    @GetMapping("/get/{id}")
    public Result<SysRoleVO> get(@PathVariable Long id) {
        if (id == null) {
            return new Result<>(CodeEnum.FAIL_100002);
        }

        SysRoleDTO dto = sysRoleService.selectById(id);
        if (dto == null) {
            return new Result<>(CodeEnum.FAIL_100010);
        }

        SysRoleVO vo = new SysRoleVO();
        BeanUtils.copyProperties(dto, vo);
        return new Result<>(vo);
    }

    @ApiOperation(value = "更新角色", notes = "根据ID更新角色信息（返回更新后完整数据）")
    @ApiImplicitParam(name = "id", value = "角色ID", required = true, paramType = "path", dataType = "Long")
    @PutMapping("/update/{id}")
    public Result<SysRoleVO> update(
            @PathVariable Long id,
            @RequestBody SysRoleSaveBO saveBO) {

        if (id == null) {
            return new Result<>(CodeEnum.FAIL_100002);
        }

        // 校验记录是否存在
        SysRoleDTO existingDto = sysRoleService.selectById(id);
        if (existingDto == null) {
            return new Result<>(CodeEnum.FAIL_100010);
        }

        // 复制非空属性（避免覆盖已有值）
        SysRoleDTO updateDto = new SysRoleDTO();
        BeanUtils.copyProperties(saveBO, updateDto);
        updateDto.setId(id);
        updateDto.setRevision(existingDto.getRevision()); // 乐观锁版本号

        boolean success = sysRoleService.updateById(updateDto);
        if (success) {
            SysRoleDTO updatedDto = sysRoleService.selectById(id);
            SysRoleVO vo = new SysRoleVO();
            BeanUtils.copyProperties(updatedDto, vo);
            return new Result<>(vo);
        }
        return new Result<>(CodeEnum.FAIL_100008);
    }

    @ApiOperation(value = "删除角色", notes = "根据ID删除角色")
    @ApiImplicitParam(name = "id", value = "角色ID", required = true, paramType = "path", dataType = "Long")
    @DeleteMapping("/delete/{id}")
    public Result<Void> delete(@PathVariable Long id) {
        if (id == null) {
            return new Result<>(CodeEnum.FAIL_100002);
        }

        boolean success = sysRoleService.deleteById(id);
        return success ? new Result<>() : new Result<>(CodeEnum.FAIL_100009);
    }

    @ApiOperation(value = "切换角色状态", notes = "根据ID切换角色状态（返回更新后数据）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色ID", required = true, paramType = "path", dataType = "Long"),
            @ApiImplicitParam(name = "status", value = "状态：0-禁用，1-启用", required = true, paramType = "query", dataType = "Integer")
    })
    @PutMapping("/changeStatus/{id}")
    public Result<SysRoleVO> changeStatus(
            @PathVariable Long id,
            @RequestParam Integer status) {

        // 业务校验
        if (status != 0 && status != 1) {
            return new Result<>(CodeEnum.FAIL_100002.getCode(), "状态值只能是0或1");
        }

        SysRoleDTO dto = sysRoleService.selectById(id);
        if (dto == null) {
            return new Result<>(CodeEnum.FAIL_100010);
        }

        dto.setStatus(status);
        dto.setRevision(dto.getRevision()); // 携带乐观锁版本号
        boolean success = sysRoleService.updateById(dto);
        if (success) {
            SysRoleDTO updatedDto = sysRoleService.selectById(id);
            SysRoleVO vo = new SysRoleVO();
            BeanUtils.copyProperties(updatedDto, vo);
            return new Result<>(vo);
        }
        return new Result<>(CodeEnum.FAIL_100008);
    }
}